
<!DOCTYPE HTML>
<html lang="" >
    <head>
        <meta charset="UTF-8">
        <meta content="text/html; charset=utf-8" http-equiv="Content-Type">
        <title>One direction data flow · React in patterns</title>
        <meta http-equiv="X-UA-Compatible" content="IE=edge" />
        <meta name="description" content="">
        <meta name="generator" content="GitBook 3.2.3">
        <meta name="author" content="Krasimir Tsonev">
        
        
    
    <link rel="stylesheet" href="../gitbook/style.css">

    
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-highlight/website.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-search/search.css">
                
            
                
                <link rel="stylesheet" href="../gitbook/gitbook-plugin-fontsettings/website.css">
                
            
        

    

    
        
        <link rel="stylesheet" href="../styles/website.css">
        
    
        
    
        
    

        
    
    
    <meta name="HandheldFriendly" content="true"/>
    <meta name="viewport" content="width=device-width, initial-scale=1, user-scalable=no">
    <meta name="apple-mobile-web-app-capable" content="yes">
    <meta name="apple-mobile-web-app-status-bar-style" content="black">
    <link rel="apple-touch-icon-precomposed" sizes="152x152" href="../gitbook/images/apple-touch-icon-precomposed-152.png">
    <link rel="shortcut icon" href="../gitbook/images/favicon.ico" type="image/x-icon">

    
    <link rel="next" href="../chapter-08/" />
    
    
    <link rel="prev" href="../chapter-06/" />
    

    </head>
    <body>
        
<div class="book">
    <div class="book-summary">
        
            
<div id="book-search-input" role="search">
    <input type="text" placeholder="Type to search" />
</div>

            
                <nav role="navigation">
                


<ul class="summary">
    
    

    

    
        
        
    
        <li class="chapter " data-level="1.1" data-path="../">
            
                <a href="../">
            
                    
                    Introduction
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="1.2" data-path="../chapter-01/">
            
                <a href="../chapter-01/">
            
                    
                    In brief
            
                </a>
            

            
        </li>
    

    
        
        <li class="header">Foundation</li>
        
        
    
        <li class="chapter " data-level="2.1" data-path="../chapter-02/">
            
                <a href="../chapter-02/">
            
                    
                    Communication
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="2.1.1" data-path="../chapter-02/">
            
                <a href="../chapter-02/#input">
            
                    
                    Input
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="2.1.2" data-path="../chapter-02/">
            
                <a href="../chapter-02/#output">
            
                    
                    Output
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="2.2" data-path="../chapter-03/">
            
                <a href="../chapter-03/">
            
                    
                    Event handlers
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="2.3" data-path="../chapter-04/">
            
                <a href="../chapter-04/">
            
                    
                    Composition
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="2.3.1" data-path="../chapter-04/">
            
                <a href="../chapter-04/#using-reacts-children-api">
            
                    
                    Using React's children API
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="2.3.2" data-path="../chapter-04/">
            
                <a href="../chapter-04/#passing-a-child-as-a-prop">
            
                    
                    Passing a child as a prop
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="2.3.3" data-path="../chapter-04/">
            
                <a href="../chapter-04/#higher-order-component">
            
                    
                    Higher-order component
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="2.3.4" data-path="../chapter-04/">
            
                <a href="../chapter-04/#function-as-a-children-render-prop">
            
                    
                    Function as a children, render prop
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="2.4" data-path="../chapter-05/">
            
                <a href="../chapter-05/">
            
                    
                    Controlled and uncontrolled inputs
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="2.5" data-path="../chapter-06/">
            
                <a href="../chapter-06/">
            
                    
                    Presentational and container components
            
                </a>
            

            
        </li>
    

    
        
        <li class="header">Data flow</li>
        
        
    
        <li class="chapter active" data-level="3.1" data-path="./">
            
                <a href="./">
            
                    
                    One direction data flow
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="3.2" data-path="../chapter-08/">
            
                <a href="../chapter-08/">
            
                    
                    Flux
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="3.2.1" data-path="../chapter-08/">
            
                <a href="../chapter-08/#flux-architecture-and-its-main-characteristics">
            
                    
                    Flux architecture and its main characteristics
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="3.2.2" data-path="../chapter-08/">
            
                <a href="../chapter-08/#implementing-a-flux-architecture">
            
                    
                    Implementing a Flux architecture
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="3.3" data-path="../chapter-09/">
            
                <a href="../chapter-09/">
            
                    
                    Redux
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="3.3.1" data-path="../chapter-09/">
            
                <a href="../chapter-09/#redux-architecture-and-its-main-characteristics">
            
                    
                    Redux architecture and its main characteristics
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="3.3.2" data-path="../chapter-09/">
            
                <a href="../chapter-09/#simple-counter-app-using-redux">
            
                    
                    Simple counter app using Redux
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    

    
        
        <li class="header">Good to know</li>
        
        
    
        <li class="chapter " data-level="4.1" data-path="../chapter-10/">
            
                <a href="../chapter-10/">
            
                    
                    Dependency injection
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="4.1.1" data-path="../chapter-10/">
            
                <a href="../chapter-10/#using-reacts-context-prior-v-163">
            
                    
                    Using React's context (prior to v. 16.3)
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.1.2" data-path="../chapter-10/">
            
                <a href="../chapter-10/#using-reacts-context-v-163-and-above">
            
                    
                    Using React's context (v. 16.3 and above)
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.1.3" data-path="../chapter-10/">
            
                <a href="../chapter-10/#using-the-module-system">
            
                    
                    Using the module system
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="4.2" data-path="../chapter-11/">
            
                <a href="../chapter-11/">
            
                    
                    Styling
            
                </a>
            

            
            <ul class="articles">
                
    
        <li class="chapter " data-level="4.2.1" data-path="../chapter-11/">
            
                <a href="../chapter-11/#the-good-old-css-class">
            
                    
                    The good old CSS class
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.2.2" data-path="../chapter-11/">
            
                <a href="../chapter-11/#inline-styling">
            
                    
                    Inline styling
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.2.3" data-path="../chapter-11/">
            
                <a href="../chapter-11/#css-modules">
            
                    
                    CSS modules
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.2.4" data-path="../chapter-11/">
            
                <a href="../chapter-11/#styled-components">
            
                    
                    Styled-components
            
                </a>
            

            
        </li>
    

            </ul>
            
        </li>
    
        <li class="chapter " data-level="4.3" data-path="../chapter-12/">
            
                <a href="../chapter-12/">
            
                    
                    Integration of third-party libraries
            
                </a>
            

            
        </li>
    
        <li class="chapter " data-level="4.4" data-path="../chapter-13/">
            
                <a href="../chapter-13/">
            
                    
                    React and separation of concerns
            
                </a>
            

            
        </li>
    

    
        
        <li class="header">Summary</li>
        
        
    
        <li class="chapter " data-level="5.1" data-path="../chapter-14/">
            
                <a href="../chapter-14/">
            
                    
                    Summary
            
                </a>
            

            
        </li>
    

    

    <li class="divider"></li>

    <li>
        <a href="https://www.gitbook.com" target="blank" class="gitbook-link">
            Published with GitBook
        </a>
    </li>
</ul>


                </nav>
            
        
    </div>

    <div class="book-body">
        
            <div class="body-inner">
                
                    

<div class="book-header" role="navigation">
    

    <!-- Title -->
    <h1>
        <i class="fa fa-circle-o-notch fa-spin"></i>
        <a href=".." >One direction data flow</a>
    </h1>
</div>




                    <div class="page-wrapper" tabindex="-1" role="main">
                        <div class="page-inner">
                            
<div id="book-search-results">
    <div class="search-noresults">
    
                                <section class="normal markdown-section">
                                
                                <h1 id="one-way-data-flow">One-way data flow</h1>
<p>One-way data flow is a pattern that works nicely with React. The idea is that components do not modify the data they receive. They only listen for changes to the data and maybe provide a new value, but they do not update the actual data. This update happens following another mechanism in another place, and the component is just re-rendered with the new value.</p>
<p>Let&apos;s, for example, examine a simple <code>Switcher</code> component that contains a button. If we click it, then we have to set a flag in the system.</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Switcher</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  <span class="hljs-keyword">constructor</span>(props) {
    <span class="hljs-keyword">super</span>(props);
    <span class="hljs-keyword">this</span>.state = { flag: <span class="hljs-literal">false</span> };
    <span class="hljs-keyword">this</span>._onButtonClick = e =&gt; <span class="hljs-keyword">this</span>.setState({
      flag: !<span class="hljs-keyword">this</span>.state.flag
    });
  }
  render() {
    <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{</span> <span class="hljs-attr">this._onButtonClick</span> }&gt;</span>
        { this.state.flag ? &apos;lights on&apos; : &apos;lights off&apos; }
      <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
    );
  }
};

<span class="hljs-comment">// ... and we render it</span>
<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Switcher</span> /&gt;</span>;
};
</span></code></pre>
<p>At this moment we have the data inside our component. Or in other words, <code>Switcher</code> is the only one place that knows about our <code>flag</code>. Let&apos;s send it out to some kind of a store:</p>
<pre><code class="lang-js"><span class="hljs-keyword">var</span> Store = {
  _flag: <span class="hljs-literal">false</span>,
  set: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
    <span class="hljs-keyword">this</span>._flag = value;
  },
  get: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>._flag;
  }
};

<span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">Switcher</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  <span class="hljs-keyword">constructor</span>(props) {
    <span class="hljs-keyword">super</span>(props);
    <span class="hljs-keyword">this</span>.state = { flag: <span class="hljs-literal">false</span> };
    <span class="hljs-keyword">this</span>._onButtonClick = e =&gt; {
      <span class="hljs-keyword">this</span>.setState({ flag: !<span class="hljs-keyword">this</span>.state.flag }, () =&gt; {
        <span class="hljs-keyword">this</span>.props.onChange(<span class="hljs-keyword">this</span>.state.flag);
      });
    }
  }
  render() {
    <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{</span> <span class="hljs-attr">this._onButtonClick</span> }&gt;</span>
        { this.state.flag ? &apos;lights on&apos; : &apos;lights off&apos; }
      <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
    );
  }
};

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Switcher</span> <span class="hljs-attr">onChange</span>=<span class="hljs-string">{</span> <span class="hljs-attr">Store.set.bind</span>(<span class="hljs-attr">Store</span>) } /&gt;</span>;
};
</span></code></pre>
<p>Our <code>Store</code> object is a <a href="https://addyosmani.com/resources/essentialjsdesignpatterns/book/#singletonpatternjavascript" target="_blank">singleton</a> where we have helpers for setting and getting the value of the <code>_flag</code> property. By passing the setter to the <code>Switcher</code> we are able to update the data externally. More or less our application workflow looks like that:</p>
<p><img src="one-direction-1.jpg" alt="one-direction data flow"></p>
<p>Let&apos;s assume that we are saving the flag value to a back-end service via the <code>Store</code>. When the user comes back we have to set a proper initial state. If the user left the flag as <code>true</code> we have to show <em>&quot;lights on&quot;</em> and not the default <em>&quot;lights off&quot;</em>. Now it gets tricky because we have the data in two places. The UI and the <code>Store</code> have their own states. We have to communicate in both directions from the store to the switcher and from the switcher to the store.</p>
<pre><code class="lang-js"><span class="hljs-comment">// ... in App component</span>
&lt;Switcher
  value={ Store.get() }
  onChange={ Store.set.bind(Store) } /&gt;

<span class="hljs-comment">// ... in Switcher component</span>
<span class="hljs-keyword">constructor</span>(props) {
  <span class="hljs-keyword">super</span>(props);
  <span class="hljs-keyword">this</span>.state = { flag: <span class="hljs-keyword">this</span>.props.value };
  ...
</code></pre>
<p>Our workflow changes to the following:</p>
<p><img src="one-direction-2.jpg" alt="one-direction data flow"></p>
<p>All this leads to managing two states instead of one. What if the <code>Store</code> changes its value based on other actions in the system. We have to propagate that change to the <code>Switcher</code> and we increase the complexity of our app.</p>
<p>One-way direction data flow solves this problem. It eliminates the multiple places where we manage states and deals with only one which is usually the store. To achieve that we have to tweak our <code>Store</code> object a little bit. We need logic that allows us to subscribe for changes:</p>
<p><span class="new-page"></span></p>
<pre><code class="lang-js"><span class="hljs-keyword">var</span> Store = {
  _handlers: [],
  _flag: <span class="hljs-string">&apos;&apos;</span>,
  subscribe: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">handler</span>) </span>{
    <span class="hljs-keyword">this</span>._handlers.push(handler);
  },
  set: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params">value</span>) </span>{
    <span class="hljs-keyword">this</span>._flag = value;
    <span class="hljs-keyword">this</span>._handlers.forEach(handler =&gt; handler(value))
  },
  get: <span class="hljs-function"><span class="hljs-keyword">function</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">this</span>._flag;
  }
};
</code></pre>
<p>Then we will hook our main <code>App</code> component and we&apos;ll re-render it every time when the <code>Store</code> changes its value:</p>
<pre><code class="lang-js"><span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">App</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">React</span>.<span class="hljs-title">Component</span> </span>{
  <span class="hljs-keyword">constructor</span>(props) {
    <span class="hljs-keyword">super</span>(props);

    <span class="hljs-keyword">this</span>.state = { value: Store.get() };
    Store.subscribe(value =&gt; <span class="hljs-keyword">this</span>.setState({ value }));
  }
  render() {
    <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">Switcher</span>
          <span class="hljs-attr">value</span>=<span class="hljs-string">{</span> <span class="hljs-attr">this.state.value</span> }
          <span class="hljs-attr">onChange</span>=<span class="hljs-string">{</span> <span class="hljs-attr">Store.set.bind</span>(<span class="hljs-attr">Store</span>) } /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
    );
  }
};
</span></code></pre>
<p>Because of this change the <code>Switcher</code> becomes really simple. We don&apos;t need the internal state and the component may be written as a stateless function.</p>
<pre><code class="lang-js"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Switcher</span>(<span class="hljs-params">{ value, onChange }</span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">onClick</span>=<span class="hljs-string">{</span> <span class="hljs-attr">e</span> =&gt;</span> onChange(!value) }&gt;
      { value ? &apos;lights on&apos; : &apos;lights off&apos; }
    <span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span></span>
  );
};

<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Switcher</span>
  <span class="hljs-attr">value</span>=<span class="hljs-string">{</span> <span class="hljs-attr">Store.get</span>() }
  <span class="hljs-attr">onChange</span>=<span class="hljs-string">{</span> <span class="hljs-attr">Store.set.bind</span>(<span class="hljs-attr">Store</span>) } /&gt;</span>
</span></code></pre>
<h2 id="final-thoughts">Final thoughts</h2>
<p>The benefit that comes with this pattern is that our components become dummy representation of the store&apos;s data. There is only one source of truth and this makes the development easier. If you are going to take one thing from this book, I would prefer it to be this chapter. The one-direction data flow drastically changed how I think when designing a feature so I believe it will have the same effect on you.</p>

                                
                                </section>
                            
    </div>
    <div class="search-results">
        <div class="has-results">
            
            <h1 class="search-results-title"><span class='search-results-count'></span> results matching "<span class='search-query'></span>"</h1>
            <ul class="search-results-list"></ul>
            
        </div>
        <div class="no-results">
            
            <h1 class="search-results-title">No results matching "<span class='search-query'></span>"</h1>
            
        </div>
    </div>
</div>

                        </div>
                    </div>
                
            </div>

            
                
                <a href="../chapter-06/" class="navigation navigation-prev " aria-label="Previous page: Presentational and container components">
                    <i class="fa fa-angle-left"></i>
                </a>
                
                
                <a href="../chapter-08/" class="navigation navigation-next " aria-label="Next page: Flux">
                    <i class="fa fa-angle-right"></i>
                </a>
                
            
        
    </div>

    <script>
        var gitbook = gitbook || [];
        gitbook.push(function() {
            gitbook.page.hasChanged({"page":{"title":"One direction data flow","level":"3.1","depth":1,"next":{"title":"Flux","level":"3.2","depth":1,"path":"chapter-08/README.md","ref":"chapter-08/README.md","articles":[{"title":"Flux architecture and its main characteristics","level":"3.2.1","depth":2,"anchor":"#flux-architecture-and-its-main-characteristics","path":"chapter-08/README.md","ref":"chapter-08/README.md#flux-architecture-and-its-main-characteristics","articles":[]},{"title":"Implementing a Flux architecture","level":"3.2.2","depth":2,"anchor":"#implementing-a-flux-architecture","path":"chapter-08/README.md","ref":"chapter-08/README.md#implementing-a-flux-architecture","articles":[]}]},"previous":{"title":"Presentational and container components","level":"2.5","depth":1,"path":"chapter-06/README.md","ref":"chapter-06/README.md","articles":[]},"dir":"ltr"},"config":{"plugins":[],"root":"./book","styles":{"website":"./styles/website.css","ebook":"./styles/ebook.css","pdf":"./styles/ebook.css"},"pluginsConfig":{"highlight":{},"search":{},"lunr":{"maxIndexSize":1000000,"ignoreSpecialCharacters":false},"sharing":{"facebook":true,"twitter":true,"google":false,"weibo":false,"instapaper":false,"vk":false,"all":["facebook","google","twitter","weibo","instapaper"]},"fontsettings":{"theme":"white","family":"sans","size":2},"theme-default":{"styles":{"website":"styles/website.css","pdf":"styles/pdf.css","epub":"styles/epub.css","mobi":"styles/mobi.css","ebook":"styles/ebook.css","print":"styles/print.css"},"showLevel":false}},"theme":"default","author":"Krasimir Tsonev","pdf":{"pageNumbers":true,"fontSize":12,"fontFamily":"Arial","paperSize":"a5","chapterMark":"pagebreak","pageBreaksBefore":"//*[@class='new-page']","margin":{"right":62,"left":62,"top":56,"bottom":56}},"structure":{"langs":"LANGS.md","readme":"README.md","glossary":"GLOSSARY.md","summary":"SUMMARY.md"},"variables":{},"title":"React in patterns","gitbook":"3.2.3","description":"A book about common design patterns used while developing with React."},"file":{"path":"chapter-07/README.md","mtime":"2025-01-27T05:05:34.247Z","type":"markdown"},"gitbook":{"version":"3.2.3","time":"2025-01-27T05:24:55.061Z"},"basePath":"..","book":{"language":""}});
        });
    </script>
</div>

        
    <script src="../gitbook/gitbook.js"></script>
    <script src="../gitbook/theme.js"></script>
    
        
        <script src="../gitbook/gitbook-plugin-search/search-engine.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-search/search.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-lunr/lunr.min.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-lunr/search-lunr.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-sharing/buttons.js"></script>
        
    
        
        <script src="../gitbook/gitbook-plugin-fontsettings/fontsettings.js"></script>
        
    

    </body>
</html>

